package com.sdy.hospitalguard.h5.controller;

import com.sdy.common.model.BizException;
import com.sdy.common.model.Response;
import com.sdy.common.utils.Assert;
import com.sdy.common.utils.StringUtil;
import com.sdy.hospitalguard.biz.constants.Constants;
import com.sdy.hospitalguard.biz.model.HospitalUser;
import com.sdy.hospitalguard.biz.service.HospitalUserService;
import com.sdy.hospitalguard.h5.config.WxConfig;
import com.sdy.hospitalguard.h5.config.WxSession;
import com.sdy.mvc.controller.BaseController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

@RestController
@RequestMapping("/login")
@Api(tags = "登录接口")
public class LoginController extends BaseController {
    @Autowired
    private HospitalUserService hospitalUserService;
    @Value("${res.app.bindphone}")
    private Boolean bindphone;
    @Value("${res.app.env.test:true}")
    private Boolean envTest;

    /**
     * 微信登录
     * @param code 微信code
     */
    @PostMapping("/wxLogin")
    @ApiOperation(value = "微信登录", notes = "登录参数根据小程序登录流程做相应修改")
    @ApiImplicitParam(value = "微信code", name = "code", required = true)
    public Response wxLogin(String code, HttpServletRequest request) throws BizException {
        Assert.isBlank(code, "微信code不能为空");
        WxSession wxSession = decryptWxId(code);
        Assert.isNull(wxSession, "微信会话解析失败。");
        request.getSession().setAttribute(Constants.SESSION_WX, wxSession);
        HospitalUser hospitalUser;
        if (bindphone) {
            // 需要绑定手机号
            hospitalUser = hospitalUserService.getUserByWxid(wxSession.getWxId());
            if (hospitalUser == null) {
                return Response.error("未绑定微信，请先使用手机号登录", -999);
            }
        } else {
            hospitalUser = hospitalUserService.xGetOrCreateUserByWxid(wxSession.getWxId());
        }
        request.getSession().setAttribute(com.sdy.common.constant.Constants.SESSION_USER_ID, hospitalUser.getId());
        return Response.success();
    }

    /**
     * 微信登录
     * @param code 微信code
     */
    @PostMapping("/wxOaLogin")
    @ApiOperation(value = "微信公众号登录")
    @ApiImplicitParam(value = "微信公众号code", name = "code", required = true)
    public Response wxOaLogin(String code, HttpServletRequest request) throws BizException {
        Assert.isBlank(code, "微信code不能为空");
        WxSession wxSession = decryptWxIdByOa(code);
        Assert.isNull(wxSession, "微信会话解析失败。");
        request.getSession().setAttribute(Constants.SESSION_WX, wxSession);
        HospitalUser hospitalUser;
        if (bindphone) {
            // 需要绑定手机号
            hospitalUser = hospitalUserService.getUserByWxid(wxSession.getWxId());
            if (hospitalUser == null) {
                return Response.error("未绑定微信，请先使用手机号登录", -999);
            }
        } else {
            hospitalUser = hospitalUserService.xGetOrCreateUserByWxid(wxSession.getWxId());
        }
        request.getSession().setAttribute(com.sdy.common.constant.Constants.SESSION_USER_ID, hospitalUser.getId());
        return Response.success();
    }

    private WxSession decryptWxId(String code) {
        WxSession wxSession = new WxSession();
        Map<String, Object> resp = WxConfig.requestMa(WxConfig.WxApi.CODE2SESSION, WxConfig.ReqMethod.GET, code);
        wxSession.setOpenId((String) resp.get("openid"));
        wxSession.setUnionId((String) resp.get("unionid"));
        wxSession.setSessionKey((String) resp.get("session_key"));
        return wxSession;
    }

    private WxSession decryptWxIdByOa(String code) {
        WxSession wxSession = new WxSession();
        Map<String, Object> resp = WxConfig.oaCodeToSession(code);
        wxSession.setOpenId((String) resp.get("openid"));
        wxSession.setUnionId((String) resp.get("unionid"));
        wxSession.setSessionKey((String) resp.get("access_token"));
        return wxSession;
    }

    @GetMapping("/logout")
    @ApiOperation(value = "登出")
    public Response logout(HttpServletRequest request) {
        request.getSession().removeAttribute(com.sdy.common.constant.Constants.SESSION_USER_ID);
        return Response.success();
    }

    @GetMapping("/testLogin")
    @ApiOperation(value = "测试登录")
    @ApiImplicitParams(value = {
            @ApiImplicitParam(value = "用户id", name = "userId"),
            @ApiImplicitParam(value = "手机号", name = "phone"),
            @ApiImplicitParam(value = "微信openId", name = "openId")
    })
    public Response testLogin(HttpServletRequest request, Integer userId, String phone, String openId) {
        if (!envTest) {
            return Response.error("请在测试环境使用。");
        }
        HospitalUser hospitalUser = null;
        if (userId != null) {
            hospitalUser = hospitalUserService.getById(userId);
        } else if (StringUtil.isNotBlank(phone)) {
            hospitalUser = hospitalUserService.getUserByPhone(phone);
        } else if (StringUtil.isNotBlank(openId)) {
            hospitalUser = hospitalUserService.getUserByWxid(openId);
        }
        if (hospitalUser != null) {
            request.getSession().setAttribute(com.sdy.common.constant.Constants.SESSION_USER_ID, hospitalUser.getId());
        } else {
            return Response.error("用户不存在。");
        }
        return Response.success("测试登录成功。");
    }
}
